package day10;

import day9.Demo6;

import java.util.Random;

public class Homework {
    public static void main(String[] args) {
        demo4();
    }
    //a.实现一个多线程统计出1-100之间  2、3、5的倍数有哪些?
    //   线程1先展示一共2的倍数有哪些
    //   线程2再展示一共3的倍数有哪些
    //   线程3最后展示一共5的倍数有哪些
    public static void demo1() {
        Thread t1=new Thread(new Demo1(2,null),"线程1");
        Thread t2=new Thread(new Demo1(3,t1),"线程2");
        Thread t3=new Thread(new Demo1(5,t2),"线程3");
        t1.start();
        t2.start();
        t3.start();

    }
    //b.写两个线程，一个线程打印 1-52，另一个线程打印A-Z，
    //打印顺序是12A34B…5152Z
    public static void demo2(){
        int len=2;
        for(int i=0;i<len;i++){
            new Demo2(i,len).start();
        }
//        new Thread(()->{
//            打印数字 26次  唤醒 等待
//        }).start();
//        new Thread(()->{
//            打印字母 26次  唤醒 等待
//        }).start();
    }
    //a.通过线程实现消费者和生产者购买商品的功能:
    //定义一个类产品类：属性 产品名称   最大数量   当前数量
    //    一个消费者线程类：属性 产品类对象
    //    一个生产者线程类:  属性  产品类对象
    //    一个测试类：初始化，运行
    //要求:生产者线程，当当前数量<最大数量时候.  生产者要进行生产.提示生产数量和当前数量
    //        生产结束后,提示消费者可以购买。
    //
    //        消费者线程, 消费者购买商品数量随机数而定，不能超过商品最大数量,如果购买数量大于商品当前数量.
    //        需要提示 购买的数量，库存不足。   呼叫生产者开始生产物品
    //        如果购买的商品数量小于商品当前数量则。正常购买 ，提示购买的数量和剩余数量
    public static void demo3(){
        Goods g=new Goods("烤鸭",10,0);
        new Product(g,"北京全聚德").start();
        new Consumer(g,"佳豪").start();
    }
    //b.编写一个程序，启动三个线程，三个线程的名
    //称分别是 A，B，C；每个线程将自己的名称在
    //屏幕上打印5遍，打印顺序是ABCABC…
    public static void demo4(){
        int len=3;//线程个数
        int count=5;//打印次数
        for(int i=0;i<len;i++){
            new PrintChar(i,len,count,(char)(65+i)+"").start();
        }

    }
}
class PrintChar extends Thread{
    int i;
    int len;
    static int maxCount;
    public PrintChar(int i,int len,int count,String name){
        super(name);
        this.i=i;
        this.len=len;
        this.maxCount=len*count;
    }
    public void run() {
        try {
            String name=Thread.currentThread().getName();
            while(maxCount!=0){
                synchronized (PrintChar.class){
                    if((15-maxCount)%len==i){
                        maxCount--;
                        System.out.print(name);
                        PrintChar.class.notifyAll();
                    }
                    PrintChar.class.wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class Goods{ //商品
    String name; //名称
    int max;  //最大容量
    int reduce; //库存
    public Goods(String name, int max, int reduce) {
        this.name = name;
        this.max = max;
        this.reduce = reduce;
    }
}
//要求:生产者线程，当当前数量<最大数量时候.  生产者要进行生产.提示生产数量和当前数量
//        生产结束后,提示消费者可以购买。
class Product extends Thread{
   Goods g;
   String name;
   public Product(Goods g,String name){
       super(name);
       this.g=g;
   }
    public void run() {
        try {
            String name=Thread.currentThread().getName();
            while(true){
                synchronized (g){
                    if(g.reduce<g.max){//库存不足 开始生产
                        //一次生产 就生产满
                        System.out.println(name+"开始生产:"+g.name+",库存:"+g.reduce+"，容量:"+g.max);
                        Thread.sleep(2000);//模拟生产时间
                        g.reduce=g.max;
                        System.out.println("生产成功,库存:"+g.reduce+",消费者可以购买了");
                    }
                    g.notifyAll();
                    g.wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
//消费者线程, 消费者购买商品数量随机数而定，不能超过商品最大数量,如果购买数量大于商品当前数量.
//需要提示 购买的数量，库存不足。   呼叫生产者开始生产物品
//如果购买的商品数量小于商品当前数量则。正常购买 ，提示购买的数量和剩余数量
class Consumer extends Thread{
    Goods g;
    String name;
    public Consumer(Goods g,String name){
        super(name);
        this.g=g;
    }
    public void run() {
        try {
            Random r=new Random();
            String name=Thread.currentThread().getName();
            while(true){
                synchronized (g){
                   int num=r.nextInt(g.max)+1;
                   if(num>g.reduce){ //库存不足 唤醒生产
                       System.out.println(name+"想购买:"+num+"个"+g.name+",但是库存:"+g.reduce);
                       System.out.println("库存不足,唤醒生产者生产");
                       g.notifyAll();
                       g.wait();
                   }
                   Thread.sleep(1000);
                   System.out.println(name+"开始购买:"+num+"个:"+
                            g.name+",剩余库存:"+(g.reduce-=num));
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Demo2 extends Thread{
    int i;
    int len;
    int num=1;
    int charNum=65;
    static int count;
    public Demo2(int i,int len){
        this.i=i;
        this.len=len;
    }
    public void run() {
        for(int j=0;j<26;j++){
            synchronized (Demo2.class) {
                try {
                    if (count++%len == i){
                        if(i==0){//打印数字
                            System.out.print(num++);
                            System.out.print(num++);
                        }else{//打印字母
                            System.out.print((char)charNum++);
                        }
                        Demo2.class.notifyAll();
                        Demo2.class.wait();
                    }else{//浪费一次循环
                        j--;
                        Demo2.class.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
class Demo1 implements Runnable{
    int n;
    Thread t;
    public Demo1(int n,Thread t){
        this.n=n;
        this.t=t;
    }
    public void run() {
        if(t!=null){
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        String name=Thread.currentThread().getName();
        for(int i=1;i<=100;i++){
            if(i%n==0){
                System.out.println(name+"求出的"+n+"倍数:"+i);
            }
        }
    }
}

